home *** CD-ROM | disk | FTP | other *** search
- ;***************************************************************************
- ;* Driver pour la Sound Blaster (calcul 10bits)
- ;*
- ;* Programmé par Sébastien Granjoux
- ;* Commencé le 11/01/95
- ;* Modification le 11/01/95
-
- IDEAL
- P386N
-
- INCLUDE "CRYSERR.INC"
- INCLUDE "CRYSDEV.INC"
- INCLUDE "CRYSLOAD.INC"
-
- PUBLIC USESB
-
- SEGMENT CODE PARA PUBLIC USE16 'CODE'
-
- ASSUME cs:CODE,ds:CODE
-
- NO_FILTER EQU 3600
- LOW_FILTER EQU 1800
-
- ;*************************************************************************
- ;* Fonction de détection du driver
-
- PROC USESB
-
- call USEDEVICE
- DEVICE <03,'BLASTERs=ApIiDd!Tt13$',OFFSET setsb,OFFSET startsb,OFFSET stopsb,OFFSET makesb,OFFSET defbpm,OFFSET peekdef,0,0,1>
-
- ENDP
-
- SbLen DW ?
- DspVer DW 0
- Count DW 0
- DmaPage DB 87h,83h,82h,81h
-
- ;***************************************************************************
- ;* Attente d'une autorisation d'écriture
- ;*
- ;* Entrée:
- ;* DX port d'écriture 2XC
- ;*
- ;* Sortie:
- ;* DX port d'écriture 2XC
-
- PROC waitsb
-
- @@wait:
- in al,dx
- or al,al
- js @@wait
-
- ret
- ENDP
-
- ;***************************************************************************
- ;* Attente d'une lecture sur un port de la SB
- ;*
- ;* Entrée:
- ;* DX adresse de port du status en lecture 2XE
- ;*
- ;* Sortie:
- ;* AL résultat de la lecture
- ;* DX adresse de port de lecture 2XA
-
- PROC readsb
-
- @@wait:
- in al,dx
- or al,al
- jns @@wait
- sub dx,4
- in al,dx
-
- ret
- ENDP
-
-
- ;***************************************************************************
- ;* Reset de la Soundblaster (recupère l'adresse de port)
- ;*
- ;* Entrée:
- ;* DS:SI adresse de la structure device
- ;*
- ;* Sortie:
- ;* DX adresse de port du reset 2X6
-
- PROC resetsb
-
- mov dx,[(DEVICE ptr ds:si).port]
- add dx,6
- mov al,1
- out dx,al
- mov cx,1024 ;compte des moutons pendant au moins 3µs
- @@compte:
- loop @@compte
- dec al
- out dx,al
- ret
-
- ENDP
-
- ;***************************************************************************
- ;* routine permettant d'initialiser le son sur la soundblaster
-
- PROC setsb
-
- call resetsb
-
- add dx,8
- mov cx,1024
- @@wait:
- in al,dx
- or al,al
- js @@test
- loop @@wait
-
- @@no_sb:
- stc
- mov ax,SB_NOT_FOUND
- ret
-
- @@test:
- sub dx,4
- in al,dx
- cmp al,0aah
- jne @@no_sb
-
- add dx,2
- call waitsb
- mov al,0E1h
- out dx,al
-
- add dx,2
- call readsb
- mov ah,al
- add dx,4
- call readsb
- mov [DspVer],ax
-
- add dx,4
- mov [cs:OFFSET port_sb+1],dx
- mov [cs:OFFSET port_sb3+1],dx
- sub dx,0eh
- mov [(DEVICE ptr ds:si).port],dx
-
- mov al,20h
- cmp [(DEVICE ptr ds:si).irq],8
- jb @@first_pic
- mov al,0A0h
- @@first_pic:
- mov [cs:OFFSET port_irq+1],al
- mov [cs:OFFSET port_irq3+1],al
-
- xor al,al ;efface la bascule interne
- out 0ch,al
-
- xor dx,dx
- mov al,[(DEVICE PTR ds:si).dma]
- mov dl,al
- add dl,al
- or al,4 ;masque le canal DMA
- out 0ah,al
-
- and al,0FBh
- or al,58h
- out 0bh,al ;choix du mode
-
- mov ax,cs
- mov cx,ax
- shr ch,4
- shl ax,4
- add ax,OFFSET SoundBuf
- cmp ax,65536-BUF_LEN
- jb @@ok1
- add ax,BUF_LEN
- adc ch,0
- mov bx,OFFSET SoundBuf
- mov [word ptr cs:OFFSET soundbuf1b+2],bx
- mov [word ptr cs:OFFSET soundbuf2b+2],bx
- mov [word ptr cs:OFFSET soundbuf3b+2],bx
- inc bx
- mov [word ptr cs:OFFSET soundbuf4b+2],bx
- mov [word ptr cs:OFFSET soundbuf5b+2],bx
- add bx,BUF_LEN
- mov [word ptr cs:OFFSET soundbuf4+2],bx
- mov [word ptr cs:OFFSET soundbuf5+2],bx
- mov [word ptr cs:OFFSET soundbuf7+2],bx
- dec bx
- mov [word ptr cs:OFFSET soundbuf1+2],bx
- mov [word ptr cs:OFFSET soundbuf2+2],bx
- mov [word ptr cs:OFFSET soundbuf3+2],bx
- mov [word ptr cs:OFFSET soundbuf6+2],bx
- @@ok1:
-
- out dx,al ; place l'adresse de base
- mov al,ah
- out dx,al
- mov ax,BUF_LEN
- dec ax
- inc dx
- out dx,al ; place la longueur du bloc
- mov al,ah
- out dx,al
- mov bx,OFFSET DmaPage
- mov al,[(DEVICE PTR ds:si).dma]
- xlat
- mov dl,al
- mov al,ch
- out dx,al
-
- mov cl,[NbVoice]
- mov al,cl
- mov ah,-1
- @@find_msbit:
- inc ah
- shr al,1
- jne @@find_msbit
- mov [cs:OFFSET nbvoicediv1+2],ah
- mov [cs:OFFSET nbvoicediv2+2],ah
- call caloptvoltab
-
- clc
-
- ret
-
- ENDP
-
- ;***************************************************************************
- ;* routine permettant de démarrer l'envoit du son sur la soundblaster
-
- PROC startsb
-
- mov ax,[VoicesLen]
- xor cl,cl
- @@search_msb:
- inc cl
- shr ax,1
- jne @@search_msb
- sub cl,2
- mov ax,1
- shl ax,cl
- mov [SbLen],ax
-
- mov ax,OFFSET soundsing
- cmp [DspVer],200h
- jbe @@old_sb
- mov ax,OFFSET soundauto
- @@old_sb:
- mov dx,cs
- mov bl,[(DEVICE PTR ds:si).irq]
- call setirq
-
- mov al,[(DEVICE PTR ds:si).dma]
- out 0ah,al ; autorise le canal DMA
-
- mov dx,1
- mov ax,086A0h ;1000000/frequence
- div [MixRate]
- neg ax
- mov ah,al
-
- mov dx,[(DEVICE PTR ds:si).port]
- add dx,04
- mov al,0Eh ; Enleve le filtre de sortie pour f>36Khz
- out dx,al
- inc dx
- in al,dx
- and al,0DFh
- cmp [ds:MixRate],NO_FILTER
- jbe @@filter_on
- or al,20h
- @@filter_on:
- out dx,al
-
- dec dx ; regle la fréquence du filtre
- mov al,0Ch
- out dx,al
- inc dx
- in al,dx
- and al,0F7h
- cmp [ds:MixRate],LOW_FILTER
- jbe @@filter32
- or al,08h
- @@filter32:
- out dx,al
-
- add dx,07h
- call waitsb
- mov al,0d1h
- out dx,al ; allume le haut parleur
-
- call waitsb
- mov al,40h
- out dx,al
- call waitsb
- mov al,ah
- out dx,al ; regle la fréquence
-
- cmp [DspVer],200h
- ja @@new_sb
-
- call waitsb
- mov al,14h
- out dx,al ; met en marche le transfert
- call waitsb
- mov ax,[ds:SbLen]
- dec ax
- out dx,al
- call waitsb
- mov al,ah
- out dx,al
-
- ret
-
- @@new_sb:
-
- call waitsb
- mov al,48h
- out dx,al
- call waitsb
- mov ax,[cs:SbLen]
- dec ax
- out dx,al
- call waitsb
- mov al,ah
- out dx,al
-
- call waitsb
- mov al,90h
- out dx,al
-
- ret
-
- ENDP
-
- ;**************************************************************************
- ;* cette procédure est en fait un bloc que l'on doit mettre à
- ;* l'adresse Voices
-
- PROC makesb FAR
-
- mov cl,[NbVoice]
- sub cl,2
- push cx
-
- mov di,OFFSET Voice1
- mov dx,[(VOICE PTR di).effet]
- call dx
-
- mov di,[ds:OFFSET SoundPage]
-
- mov bx,[(VOICE PTR Voice1).play]
- shl bx,1
- xor edx,edx
- mov dx,[word ptr ds:bx+OFFSET Notes]
-
- ror edx,10
- mov cx,[(VOICE PTR Voice1).samplen]
- les esi,[(VOICE PTR Voice1).adrvoc]
- mov bx,[(VOICE PTR Voice1).replen]
- cmp si,cx
- jbe @@ok1
- @@adjust1:
- sub si,bx
- cmp si,cx
- ja @@adjust1
- @@ok1:
-
- mov bx,OFFSET VolumeTab
- mov al,[MasterVol]
- and al,[(VOICE PTR Voice1).mute]
- mul [(VOICE PTR Voice1).volume]
- add bh,ah
-
- push ebp
- @@voix1:
- add esi,edx
- mov al,[byte ptr es:si]
- adc esi,edx
- xlat
- mov ah,al
- mov al,[byte ptr es:si]
- adc si,0
- xlat
- soundbuf1:
- mov [ds:di+OFFSET SoundBuf],ax
- soundbuf1b:
- mov [word ptr ds:di+OFFSET SoundBuf+BUF_LEN],0
- add di,2
-
- cmp di,bp
- jne @@voix1
- rol ebp,16
- xor di,di
- cmp bp,BUF_LEN
- jne @@voix1
- pop ebp
-
- mov [dword ptr ((VOICE PTR Voice1).adrvoc)],esi
-
- pop cx
- mov di,OFFSET Voice1+SIZE VOICE
- @@next_voice:
- push cx
- mov dx,[(VOICE ptr ds:di).effet]
- call dx
-
- mov bx,[(VOICE ptr ds:di).play]
- shl bx,1
- xor edx,edx
- mov dx,[word ptr ds:bx+OFFSET Notes]
- ror edx,10
- mov cx,[(VOICE ptr ds:di).samplen]
- les esi,[(VOICE ptr ds:di).adrvoc]
- mov bx,[(VOICE ptr ds:di).replen]
- cmp si,cx
- jbe @@ok2
- @@adjust2:
- sub si,bx
- cmp si,cx
- ja @@adjust2
- @@ok2:
-
- mov bx,OFFSET VolumeTab
- mov al,[MasterVol]
- and al,[(VOICE PTR ds:di).mute]
- mul [(VOICE PTR ds:di).volume]
- add bh,ah
-
- push di
-
- push ebp
- mov di,[ds:OFFSET SoundPage]
- @@voix2:
- add esi,edx
- mov al,[byte ptr es:si]
- adc esi,edx
- xlat
- mov ah,al
- mov al,[byte ptr es:si]
- adc si,0
- xlat
- soundbuf2:
- add [ds:di+OFFSET SoundBuf],al
- soundbuf2b:
- adc [byte ptr ds:di+OFFSET SoundBuf+BUF_LEN],0
- soundbuf4:
- add [ds:di+OFFSET SoundBuf+1],ah
- soundbuf4b:
- adc [byte ptr ds:di+OFFSET SoundBuf+BUF_LEN+1],0
- add di,2
-
- cmp di,bp
- jne @@voix2
- rol ebp,16
- xor di,di
- cmp bp,BUF_LEN
- jne @@voix2
- pop ebp
-
-
- pop di
- mov [dword ptr ((VOICE ptr ds:di).adrvoc)],esi
- add di,SIZE VOICE
- pop cx
- dec cl
- jne @@next_voice
-
- mov dx,[(VOICE ptr ds:di).effet]
- call dx
-
- mov bx,[(VOICE ptr ds:di).play]
- shl bx,1
- xor edx,edx
- mov dx,[word ptr ds:bx+OFFSET Notes]
- ror edx,10
- mov cx,[(VOICE ptr ds:di).samplen]
- les esi,[(VOICE ptr ds:di).adrvoc]
- mov bx,[(VOICE ptr ds:di).replen]
- cmp si,cx
- jbe @@ok4
- @@adjust4:
- sub si,bx
- cmp si,cx
- ja @@adjust4
- @@ok4:
-
- mov bx,OFFSET VolumeTab
- mov al,[MasterVol]
- and al,[(VOICE ptr ds:di).mute]
- mul [(VOICE ptr ds:di).volume]
- add bh,ah
-
- push di
- mov di,[ds:OFFSET SoundPage]
- xor ah,ah
- @@voix4:
- add esi,edx
- mov al,[byte ptr es:si]
- adc si,0
- xlat
- soundbuf3:
- add al,[ds:di+OFFSET SoundBuf]
- soundbuf3b:
- adc ah,[ds:di+OFFSET SoundBuf+BUF_LEN]
- nbvoicediv1:
- shr ax,2
-
- soundbuf6:
- mov [byte ptr ds:di+OFFSET SoundBuf],al
- add esi,edx
- mov al,[byte ptr es:si]
- adc si,0
- xlat
- soundbuf5:
- add al,[ds:di+OFFSET SoundBuf+1]
- soundbuf5b:
- adc ah,[ds:di+OFFSET SoundBuf+BUF_LEN+1]
- nbvoicediv2:
- shr ax,2
-
- soundbuf7:
- mov [byte ptr ds:di+OFFSET SoundBuf+1],al
- add di,2
-
- cmp di,bp
- jne @@voix4
- rol ebp,16
- xor di,di
- cmp bp,BUF_LEN
- jne @@voix4
-
- pop di
- mov [dword ptr ((VOICE ptr ds:di).adrvoc)],esi
-
- @@fin4voice:
-
- shr ebp,16
- and bp,65535-BUF_LEN
- mov [word ptr ds:OFFSET SoundPage],bp
- mov [byte ptr cs:OFFSET switch_makemod],1Eh
-
- pop edi
- pop esi
- pop ebp
- pop es
- pop ds
-
- ret
-
- ENDP
-
- ;***************************************************************************
- ;* Cette routine remplace d'interruption de la sound blaster
-
- PROC soundsing
-
- push ax
- push dx
-
- port_sb:
- mov dx,22eh
- in al,dx
- sub dx,2
-
- @@wait1:
- in al,dx
- or al,al
- js @@wait1
- mov al,14h
- out dx,al
-
- @@wait2:
- in al,dx
- or al,al
- js @@wait2
- mov ax,[cs:SbLen]
- add [cs:SoundPtr],ax
- and [cs:SoundPtr],65535-BUF_LEN
- dec ax
- out dx,al
-
- @@wait3:
- in al,dx
- or al,al
- js @@wait3
- mov al,ah
- out dx,al
-
- mov al,20h
- out 20h,al
- port_irq:
- out 20h,al
- pop dx
-
- mov ax,[cs:SbLen]
- sub [cs:Count],ax
- jle @@imakemod
- pop ax
-
- iret
-
- @@imakemod:
- mov ax,[cs:VoicesLen]
- add [cs:Count],ax
- pop ax
-
- jmp IMAKEMOD
-
- ENDP
-
- ;***************************************************************************
- ;* Cette routine remplace d'interruption de la sound blaster
-
- PROC soundauto
-
- push ax
- push dx
-
- port_sb3:
- mov dx,22eh
- in al,dx
-
- mov ax,[cs:SbLen]
- add [cs:SoundPtr],ax
- and [cs:SoundPtr],65535-BUF_LEN
-
- mov al,20h
- out 20h,al
- port_irq3:
- out 20h,al
- pop dx
-
- mov ax,[cs:SbLen]
- sub [cs:Count],ax
- jle @@imakemod
- pop ax
-
- iret
-
- @@imakemod:
- mov ax,[cs:VoicesLen]
- add [cs:Count],ax
- pop ax
-
- jmp IMAKEMOD
-
- ENDP
-
- ;***************************************************************************
- ;* Cette routine permet d'arreter l'envoit du son sur une soundblaster
-
- PROC stopsb
-
- call resetsb
-
- mov al,[(DEVICE PTR ds:si).dma] ; masque le canal DMA
- or al,4
- out 0ah,al
-
- add dx,6
- call waitsb
- mov al,0d3h
- out dx,al ; éteint le haut parleur
-
- sub dx,08
- mov al,0Eh ; remet le filtre
- out dx,al
- inc dx
- in al,dx
- and al,0DFh
- out dx,al
-
- dec dx ; remet le filtre à 3.2Khz
- mov al,0Ch
- out dx,al
- inc dx
- in al,dx
- and al,0F7h
- out dx,al
-
- ret
-
- ENDP
-
- ENDS
-
- END